<?php

class Buyback_Model_Cart implements SeekableIterator, Countable, ArrayAccess
{
	protected $_items = array();
	
	protected $_Total = 0;
	
	protected $_SessionNamespace;
	
	
	public function __construct()
	{
		$this->init();
	}
	public function init()
    {
    	$this->loadSessionNamespace();
    }
	
    public function addValidItem(Buyback_Resource_Offer_Item $offerItem){
    	
    	if(0 >= $offerItem->Quantity){
    		//Remove Item
    		return true;
    	}
    	
    	$cartItem = new Buyback_Resource_Cart_ValidItem($offerItem);
    	
    	$this->_items[$cartItem->Id] = $cartItem;
		$this->persist();
		return $cartItem;
    	
    	
    }
    
    public function addInvalidItem($id, $message){
    	
    	$cartItem = new Buyback_Resource_Cart_InvalidItem($id, $message);
    	
    	$this->_items[$cartItem->Id] = $cartItem;
    	$this->persist();
    	return $cartItem;
    }
    
    public function updateCartItem($id, $qnty){
    	if($this->offsetExists($id) && ("Invalid Item" != $this->offsetGet($id)->ItemType)){
    		
    		if(0 == $qnty){
    			$this->removeItem($id);
    		}else{
    			$this->offsetGet($id)->Quantity = $qnty;
    		}
    	}
    	$this->persist();
    }
    
    public function removeItem($id = null){

    	if($this->offsetExists($id)){
    		unset($this->_items[$id]);
    		$this->persist();
    		return true;
    	}

    	$this->_items = array();
    	$this->persist();
    	return true;
    }
    
    public function hasItem(){
    	if(empty($this->_items)){
    		return false;
    	}
    	return true;
    }
	
    public function setOfferPrice(){
		
		$this->_Total = 0;
		foreach($this->_items as $item)
		{
			if($item instanceOf Buyback_Resource_Cart_ValidItem)
			$this->_Total += $item->Offers->OfferPrice * $item->Quantity;
		}
	}
	
	public function getOfferPrice(){
		$this->setOfferPrice();
		return $this->_Total;
	}
	
	public function getValidItemCount(){
		 $count = 0;
		 foreach($this->_items as $item){
		 	if($item instanceOf Buyback_Resource_Cart_ValidItem)
		 		$count++;
		 }
		 return $count;
	}
	
	public function setSessionNamespace(Zend_Session_Namespace $namespace)
	{
		$this->_SessionNamespace = $namespace;
	}
	
	public function getSessionNamespace()
	{
		if(is_null($this->_SessionNamespace)){
			$this->setSessionNamespace(new Zend_Session_Namespace(__CLASS__));
		}
		return($this->_SessionNamespace);
	}
	
	public function persist()
	{
		$this->getSessionNamespace()->_items = $this->_items;
		$this->getSessionNamespace()->_Total = $this->getOfferPrice();
	}
	
	public function loadSessionNamespace()
	{
		if (isset($this->getSessionNamespace()->_items)) {
            $this->_items = $this->getSessionNamespace()->_items;
        }
        if (isset($this->getSessionNamespace()->_Total)) {
        	$this->_Total = $this->getOfferPrice();
        }
	}

	/**
     * Does the given offset exist?
     *
     * @param string|int $key key
     * @return boolean offset exists?
     */
    public function offsetExists($key)
    {
        return isset($this->_items[$key]);
    }

    /**
     * Returns the given offset.
     *
     * @param string|int $key key
     * @return mixed
     */
    public function offsetGet($key)
    {
        return $this->_items[$key];
    }

    /**
     * Sets the value for the given offset.
     *
     * @param string|int $key
     * @param mixed $value
     */
    public function offsetSet($key, $value)
    {
        return $this->_items[$key] = $value;
    }

    /**
     * Unset the given element.
     *
     * @param string|int $key
     */
    public function offsetUnset($key)
    {
        unset($this->_items[$key]);
    }

    /**
     * Returns the current row.
     *
     * @return array|boolean current row 
     */
    public function current()
    {
        return current($this->_items);
    }

    /**
     * Returns the current key.
     *
     * @return array|boolean current key
     */
    public function key()
    {
        return key($this->_items);
    }

    /**
     * Moves the internal pointer to the next item and
     * returns the new current item or false.
     *
     * @return array|boolean next item
     */
    public function next()
    {
        return next($this->_items);
    }

    /**
     * Reset to the first item and return.
     *
     * @return array|boolean first item or false
     */
    public function rewind()
    {
        return reset($this->_items);
    }

    /**
     * Is the pointer set to a valid item?
     *
     * @return boolean valid item?
     */
    public function valid()
    {
        return current($this->_items) !== false;
    }

    /**
     * Seek to the given index.
     *
     * @param int $index seek index
     */
    public function seek($index)
    {
        $this->rewind();
        $position = 0;

        while ($position < $index && $this->valid()) {
            $this->next();
            $position++;
        }

        if (!$this->valid()) {
            throw new Exception('Invalid seek position');
        }
    }

    /**
     * Count the cart items
     *
     * @return int row count
     */
    public function count()
    {
        return count($this->_items);
    }
}